﻿//-----------------------------------------------------------------------
// <copyright file="State.cs" company="Sławomir Rosiek">
//     Copyright (c) Sławomir Rosiek. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace Rosieks.Web.Flow.Metadata
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Web.Mvc;
    using System.Web.Routing;
    using Rosieks.Web.Flow.Resources;

    [DebuggerDisplay("{Name, nq} : {GetType().Name, nq}")]
    public abstract partial class State : IExecutionObject
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="T:State"/> class.
        /// </summary>
        public State()
        {
        }

        public Transition[] Transitions
        {
            get;
            set;
        }

        public virtual void OnAction(WebflowContext webflowContext, string actionName, ControllerContext context)
        {
            if (!string.IsNullOrEmpty(actionName))
            {
                Transition[] transitions = null;
                Transition actionTransition;
                if (!ActionTransition.TryParse(actionName, webflowContext, out actionTransition))
                {
                    transitions = this.Transitions.Where(t => t.On == actionName).ToArray();
                }
                else
                {
                    transitions = new[] { actionTransition };
                }

                if (transitions.Length == 0)
                {
                    throw new ArgumentException(string.Format(WebflowResources.Common_InvalidActionName, actionName, this.Name));
                }
                else
                {
                    var transition = transitions.FirstOrDefault(t => t.IsValid(context)) ?? new NoTransition(this);

                    webflowContext.ChangeState(transition);
                }
            }
        }

        public bool IsRequestedStep(RequestContext context)
        {
            return !this.RouteData.Values
                .Select(State.ToKeyValuePair)
                .Except(context.RouteData.Values.Select(State.ToKeyValuePair))
                .Any();
        }

        internal void OnEnter(WebflowContext webflowContext, ControllerContext context)
        {
            throw new NotImplementedException();
        }

        internal void OnLeave(WebflowContext webflowContext, ControllerContext context)
        {
            throw new NotImplementedException();
        }

        private static KeyValuePair<string, object> ToKeyValuePair(KeyValuePair<string, object> routeData)
        {
            return new KeyValuePair<string, object>(routeData.Key, routeData.Value.ToString());
        }
    }
}
